﻿using Mapster;
using Shipeng.Domain.Entities;
using Shipeng.Domain.Shared.Enums;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using Yarp.ReverseProxy.Health;

namespace Shipeng.Domain.ReverseProxy
{
    internal class ClusterManager : DomainService, IClusterManager
    {
        private readonly IRepository<Cluster> _clusterRepository;
        public ClusterManager(IRepository<Cluster> clusterRepository)
        {
            _clusterRepository = clusterRepository;
        }

        public async Task<Cluster> CreateAsync(Guid routeId, string clusterName, ServiceGovernanceType serviceGovernanceType, string serviceGovernanceName, string loadBalancingPolicy)
        {
            var cluster = await _clusterRepository.FindAsync(x => x.RouteId == routeId);
            if (cluster != null)
            {
                throw new Exception("同一个路由下只能创建一个集群");
            }
            return new Cluster(GuidGenerator.Create())
            {
                ClusterName = clusterName,
                RouteId = routeId,
                ServiceGovernanceName = string.IsNullOrEmpty(serviceGovernanceName) ? "" : serviceGovernanceName,
                ServiceGovernanceType = serviceGovernanceType,
                LoadBalancingPolicy = loadBalancingPolicy
            };
        }
        public Task<ClusterDestination> CreateClusterDestinationAsync(Guid clusterId, string destinationName, string destinationAddress)
        {
            return Task.Factory.StartNew(() =>
            {
                return new ClusterDestination(GuidGenerator.Create())
                {
                    DestinationAddress = destinationAddress,
                    ClusterId = clusterId,
                    DestinationName = destinationName
                };
            });
        }

        public Task<ClusterHealthCheck> CreateHealthCheckAsync<TDto>(TDto healthCheck) where TDto : class
        {
            return Task.Factory.StartNew(() =>
            {
                var model = new ClusterHealthCheck(GuidGenerator.Create());
                model.Policy = HealthCheckConstants.ActivePolicy.ConsecutiveFailures;
                TypeAdapter.Adapt(healthCheck, model);
                return model;
            });
        }
    }
}
